//////////////////////////////
0x0203E026 - ram location of weapon/spell animation association value

0x08C999C0 - rom start of spell animation association per weapon table

.org				0x08055896
ldr	r1,	[pc,	#0x1C]	@=#0x08BA13D0
@-------------------------------@Spell animation PC table
mov	r2,	#0x0		@
ldsh	r0,	[r0,	r2]	@Loads spell ID
lsl	r0,	r0,	#0x2	@
add	r0,	r0,	r1	@
ldr	r1,	[r0]		@Get PC ref
mov	r0,	r5		@
bl				#0x080BFC50

.org				0x080BFC50
bx	r1			@Oh joy
nop

@-------------------------------@Sword of Seals
.org				0x0805779C
push	{r4, r5, lr}		@
mov	r5,	r0		@
bl				0x0804FFF0
@-------------------------------@Screen dimming is handled by this call
bl				0x0804FB6C
bl				0x08050008
@-------------------------------@Only difference between routines is here:
ldr	r0,	[pc,	#0x24]	@=#0x08BA1874
mov	r1,	#0x3		@
bl				0x08004494
mov	r4,	r0		@
str	r5,	[r4,	#0x5C]	@
mov	r0,	#0x0		@
strh	r0,	[r4,	#0x2C]	@
mov	r0,	r5		@
bl				0x08054804
lsl	r0,	r0,	#0x10	@
asr	r0,	r0,	#0x10	@
bl				0x0805468C
add	r4,	#0x29		@
strb	r0,	[r4]		@
pop	{r4, r5}		@
pop	{r0}			@
bx	r0			@Sword of Seals complete!

@-------------------------------@Divine
.org				0x0805AE90
push	{r4, r5, lr}		@
mov	r5,	r0		@
bl				0x0804FFF0
bl				0x0804FB6C
bl				0x08050008
@-------------------------------@Only difference between routines is here:
ldr	r0,	[pc,	#0x24]	@=#0x08BA29A8

Pointer that differs above should point to this:

Struct 0x18 bytes in size

+0x00	Word set to 0x00000019
+0x04	Word of 0
+0x08	Word set to 0x00000003
+0x0C	PC to execute
+0x10	Word of 0
+0x14	Word of 0

@-------------------------------@Sword of Seals
@-------------------------------@Comparing to Divine;
@-------------------------------@most of the time the two routines are the same
@-------------------------------@except where specified (haven't finished comparing the two)
@-------------------------------@IMPORTANT: Screen dimming is handled before this, but this routine
@-------------------------------@handles screen shifting. It is also only called a few times during
@-------------------------------@the animation; in other words, it sets up the animation in "chunks"
@-------------------------------@and is called again when the previous chunk has been processed
.org				0x080577D8
push	{r4-r7, lr}		@
add	sp,	#-0x8		@Divine doesn't do this
add	r4,	r0,	#0x0	@
ldr	r0,	[r4,	#0x5C]	@Loads pointer to AIS for unit casting this spell
bl				0x080547A8
add	r5,	r0,	#0x0	@Puts returned pointer to target unit's AIS into r5
bl				0x08050778
add	r6,	r0,	#0x0	@Divine uses r3; seems to return ID of next frame to do something
@-------------------------------@on, minus 1 (returns 0x10 for this animation)
ldrh	r0,	[r4,	#0x2C]	@Load ID of frame to execute
add	r0,	#0x1		@FrameID++
mov	r7,	#0x0		@Divine doesn't do this
strh	r0,	[r4,	#0x2C]	@FrameID++
lsl	r0,	r0,	#0x10	@
asr	r0,	r0,	#0x10	@
cmp	r0,	#0x1		@Check if frame ID is 0x01
bne				0x08057806
ldr	r0,	[r4,	#0x5C]	@From here-----
mov	r1,	#0x1		@
neg	r1,	r1		@
@-------------------------------@Scrolls the screen
bl				0x0804E498
.org				0x08057806
mov	r0,	#0x2C		@
ldsh	r1,	[r4,	r0]	@Reload current frame ID
add	r0,	r6,	#0x1	@Check if frame ID is 0x11
cmp	r1,	r0		@-----through here occurs after the difference below
bne				0x08057854
@-------------------------------@Load SoS fire music value
@-------------------------------@This frame is responsible for initializing and starting playing of
@-------------------------------@the actual animation
ldr	r0,	[pc,	#0x3C]	@=#0x0000010D
mov	r1,	#0x80		@
lsl	r1,	r1,	#0x1	@
mov	r3,	#0x2		@
ldsh	r2,	[r5,	r3]	@
mov	r3,	#0x1		@
@-------------------------------@Play music routine
bl				0x080681E4
add	r0,	r5,	#0x0	@
@-------------------------------@Divine calls 0x0805AFBC here instead;
@-------------------------------@Using Divine's call makes the first Divine shot go up (in the wrong
@-------------------------------@place, no less, because the screen will have already shifted) and the
@-------------------------------@call below makes the fire appear for this animation; not responsible
@-------------------------------@for "hitting" the enemy
@-------------------------------@This routine immediately loads pointers to streams of PCs to execute
@-------------------------------@and OAM data, calling functions after each case; also does this with 
@-------------------------------@TSA (?) and sheet pointers
bl				0x08057894
ldr	r0,	[r4,	#0x5C]	@
mov	r1,	#0x6		@Divine doesn't do this; instead, it calls
@-------------------------------@0x0805B1EC
@-------------------------------@Divine doesn't make the call below; the function below immediately
@-------------------------------@loads 0x08B9AE4C, a pointer to a vector in the format:

0x00000019 - Start
0x00000000 - NOP; terminate if next word is NOP?
0x000A000F - What?
0x00000000 - NOP
0x00000003 - Execute this routine:
0x0804F0B1 - Address to BX to

These v ^ routines seem negligible :/

0x00000003 - Execute this routine:
0x0804F0E8 - Address to BX to
0x00000000 - Terminator part 1
0x00000000 - Terminator part 2

@-------------------------------@Not sure what this routine does but seems unnecessary
bl				0x0804EFDC
mov	r0,	#0x9		@Divine doesn't do this; instead, it branches to
@-------------------------------@0x0805AFB6 (exit)
@-------------------------------@The bits in 0x09 are "hit" flags that indicate that the target has been
@Divine has:
@-------------------------------@
@.long				0x00000127
@cmp	r2,	#0x14
@bne				0x0805AF24
@Else: Play music of ID 0x0094
@-------------------------------@From here-----
ldrh	r1,	[r5,	#0x10]	@Load target's status flags
orr	r0,	r1		@Set "hit" flags that were immediately loaded
strh	r0,	[r5,	#0x10]	@Update status flags
add	r4,	#0x29		@
ldrb	r1,	[r4,	#0x0]	@
add	r0,	r5,	#0x0	@
@-------------------------------@The following routine is responsible for subtracting from the target's
@-------------------------------@health bar but is not needed to "hit" the enemy (though it looks weird
@-------------------------------@to leave this routine out >.>)
bl				0x08050140
ldrb	r0,	[r4,	#0x0]	@
cmp	r0,	#0x0		@
bne				0x0805788A
add	r0,	r5,	#0x0	@
@-------------------------------@This routine plays the "hit target" sound
@-------------------------------@using the target's AIS pointer as the only argument
bl				0x08067D14
b				0x0805788A
lsl	r0,	r0,	#0x0	@
.long				0x0000010D
.org				0x08057854
add	r0,	r6,	#0x0	@
add	r0,	#0x1C		@
cmp	r1,	r0		@Check if frame is 0x2C
bne				0x0805786E
@-------------------------------@The animation cannot complete if this frame is looped
str	r7,	[sp,	#0x0]	@These
str	r7,	[sp,	#0x4]	@two lines zero some local variables
add	r0,	r5,	#0x0	@
mov	r1,	#0x0		@
mov	r2,	#0xE		@
mov	r3,	#0x10		@
@-------------------------------@Not sure what this routine does but seems unnecessary
bl				0x08055F08
b				0x0805788A
.org				0x0805786E
add	r0,	r6,	#0x0	@
add	r0,	#0x32		@
cmp	r1,	r0		@Check if frame is 0x42 (unused >.>)
beq				0x0805788A
add	r0,	#0x5		@Below: Check if frame is 0x47
cmp	r1,	r0		@-----through here are animation specific checks of the current frame ID
@-------------------------------@for calling routines responsible for the special effects unique to
@-------------------------------@each animation; except for the difference in registers popped and the
@-------------------------------@odd stack write related SP increment the SoS animation does, the rest of
@-------------------------------@this routine is paraphrased in the Divine animation routine
bne				0x0805788A
@-------------------------------@Terminate spell animation and allow caster to continue
bl				0x0804FFFC
bl				0x0804FBC4
add	r0,	r4,	#0x0	@
bl				0x080046A0
.org				0x0805788A
add	sp,	#0x8		@
pop	{r4-r7}			@
pop	{r0}			@
bx	r0			@Sword of Seals complete!

@-------------------------------@Divine
.org				0x0805AECC
@-------------------------------@Compared within to the SoS doc above

.org				0x0805B246
ldr	r0,	[pc,	#0x14]	@=#0x08242348
@-------------------------------@Loads a sheet for part of the Divine animation

.org				0x08057894
push	{r4-r5, lr}		@
add	sp,	#-0x4		@
mov	r5,	r0		@
ldr	r1,	[pc,	#0x50]	@=#0x0201774C
ldr	r0,	[r1]		@
add	r0,	#0x1		@
str	r0,	[r1]		@
ldr	r0,	[pc,	#0x4C]	@=#0x08BA188C - PC list
mov	r1,	#0x3		@
bl				0x08004494
mov	r4,	r0		@
str	r5,	[r4,	#0x5C]	@
mov	r0,	#0x0		@
strh	r0,	[r4,	#0x2C]	@
mov	r0,	#0x34		@
strh	r0,	[r4,	#0x2E]	@
mov	r0,	r5		@
bl				0x08054678
ldr	r3,	[pc,	#0x34]	@=#0x08BA7F18 - Vector of OAM pointers (left to right)
cmp	r0,	#0x0		@
bne				0x08057C84
ldr	r3,	[pc,	#0x34]	@=#0x08BA72B8 - Vector of OAM pointers (right to left)
.org				0x08057C84
str	r3,	[sp]		@
mov	r0,	r5		@
mov	r1,	r3		@
bl				0x0805041C
str	r0,	[r4,	#0x60]	@
ldr	r0,	[pc,	#0x28]	@=#0x081EF21C - Palette data
mov	r1,	#0x20		@32 bytes in a palette
bl				0x080505F0
ldr	r0,	[pc,	#0x24]	@=#0x081EE51C - Sheet data (limited to 128 tiles)
mov	r1,	#0x80		@128 tiles
lsl	r1,	r1,	#0x5	@32 bytes per tile
bl				0x080505C8
add	sp,	#0x4		@
pop	{r4, r5}		@
pop	{r0}			@
bx	r0			@*Whew* SoS graphic loading complete!

Parts of a spell animation:

- Constructor
	Iinitialization; handles screen dimming where appropriate and sets loads a callback to
	the processor with a pointer to callback data
- Callback data
	19 00 00 00
	00 00 00 00
	03 00 00 00
	Thumb PC of processor
	00 00 00 00
	00 00 00 00
- Processor
	This is either a giant if-else block or switch statement with the value
	to test being the ID of which frame in the animation is processing; calls "animation
	chunk" routines when graphics are to be displayed and sound routines with hardcoded sound
	values when sounds are to be played, etc.
- Animation chunk
	This subroutine initializes palette data, OAM stream pointers and sheet data for the
	sprites to be displayed (likely also the background to be displayed; I haven't seen a case
	of this yet as I've only looked at the SoS animation, which has no backgrounds)
	Loads a series of callbacks to sprite drawing code
- Callback data
	Remember this from earlier?
0x00000019 - Start
0x00000000 - NOP; terminate if next word is NOP?
0x000A000F - What?
0x00000000 - NOP
0x00000003 - Execute this routine:
0x0804F0B1 - Address to BX to

"These v ^ routines seem negligible :/" - I may have been wrong; didn't test thoroughly

0x00000003 - Execute this routine:
0x0804F0E8 - Address to BX to
0x00000000 - Terminator part 1
0x00000000 - Terminator part 2
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
Animation interpreter structs

0x48 bytes in size

0x02028E78 - Left unit's struct
0x02028F08 - Right unit's struct

+0x00	Flag byte
		AND 0x02: True when cape flowing? Acts as though AND 0x01 is false?
		AND 0x01: True to display sprites/continue animation
+0x02	X offset based on screen scroll
+0x06	Byte of delay countdown
+0x08	Halfword of basis for part 2 of 0-2 of OAM data (which selects which tile is the top left corner)
		0x9B00 for right unit (name = 0x300; tile 768 where the sheet is loaded to)
+0x13	Byte of frame ID
+0x15	Byte of ID of 0x85 command being executed
+0x20	Frame pointer
+0x24	Pointer to last 0x86 command?
+0x30	OAM start pointer
+0x34	Parent AIS (drawn before this one)
+0x38	Child AIS (drawn after this one)
+0x3C	OAM pointer

To initialize both AISs:

R00	Mode for left unit (immediate 8)
R01	Mode for right unit (immediate 8)
Call	0x080542D8

To initialize an AIS:

0x02000060 = ROM pointer of section data (The location this has to be at may be changed; see below)
R00	Mode (0 based; modes are labeled with 1 as the base in these notes) (Should be 8)
Call	0x08054474 - Will use right unit addresses; this will need to be remedied by copying the
	function to elsewhere and modifying the constants

.org				0x080064CC
bl				0x08006688
@-------------------------------@Seems to be the only location of this call

To process the current frame of an animation:

@R00 == Pointer to animation interpreter struct
bl				0x08006688
@Returns a boolean of unknown purpose
@Updates sheet and OAM pointers in the struct or queues an 0x85 command
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
+0x08 of an AIS: top 4 bits of the 16 bit little endian short here controls palette to use for a sprite
+0x34 of an AIS points to the previous AIS to draw
+0x38 of an AIS points to the next AIS to draw; null terminates the cycle
0x02000000 points to the left unit AIS
0x02000008 points to the right unit AIS
0x02029C88 points to parent AIS
- How to add sprites normally
{
	For FE 7:
		With dummy AIS struct at HI_DUMMY_AIS_PTR (user defined)
		Set +0x00 |= 1
		Set +0x02 to X offset (defender's or attacker's)
		Set +0x04 to +0x04 of attacker or defender AIS
		Set +0x06 to anything > 0
		Set +0x08 to 0x2840
			(usual OAM flags and name base = 0x040, where spell OAM sheets go)
		Set +0x1C to 0x00000000
		Set +0x20 to point to dummy frame data
		Set +0x30 to point to beginning of OAM
		Set +0x34 to null
		Set +0x38 to point to attacker AIS

		Set 0x02029C88 = dummy AIS ref
}
- How to add them specifically with low priority
{
	For FE 7:
		With dummy AIS struct at LOW_DUMMY_AIS_PTR (user defined)
		Set +0x00 |= 1
		Set +0x02 to X offset (defender's or attacker's)
		Set +0x04 to +0x04 of attacker or defender AIS
		Set +0x06 to anything > 0
		Set +0x08 to 0x2840
			(usual OAM flags and name base = 0x040, where spell OAM sheets go)
		Set +0x1C to 0x00000000
		Set +0x20 to point to dummy frame data
		Set +0x30 to point to beginning of OAM
		Set +0x34 to point to defender AIS
		Set +0x38 to point to defender AIS's child AIS

		With defender's AIS
		Set +0x38 to point to dummy AIS
}
- Dummy frame data should be
[halfword of frame delay] [byte of frame ID] 86
[word of OAM sheet pointer]
[word of OAM data offset]
Here should probably be 01 00 00 85, or at least 00 00 00 80, though preferably
01 03 00 85 (Loops back to 86 "frame command" using my 01 command hack; allows to wait for user
termination)
- How to process 0x85 commands the usual way
{
	Set +0x06 of attacker's AIS struct += 0x0001
	Set +0x0C of attacker's AIS struct &= 0x0FFF
	Set +0x0C of attacker's AIS struct |= 0x1000
	Set +0x14 of attacker's AIS struct to true (|= 1)
	Set +0x15 of attacker's AIS struct to the command value
}
Note: Data at
0x03002870 (FE 7)
0x03003080 (FE 8)
is copied over BG I/O registers
- How to stretch the map1 display channel
{
	Set 0x04000004 AND 0x10 to true to double vertical scale
		0x03002874 for FE 7
		0x03003084 for FE 8
}
- How to set the opacity of map1
{
	Set 0x04000050 to 0x3C42 to enable transparency
		0x030028AC for FE 7
		0x030030BC for FE 8
	Set 0x04000052 AND 0x1F to brightness level from 0-16
		(0 - black, 16 - original colors)
		0x030028B4 for FE 7
		0x030030C4 for FE 8
	Set 0x04000053 AND 0x1F to transparency level from 0-16
		(0 - 100% opaque, 16 - 50% opaque)
		0x030028B5 for FE 7
		0x030030C5 for FE 8
}
- How to toggle the viewability of map2/map3
{
	Set 0x04000001 AND 0x08 to true to enable or false to disable (background map3)
	Set 0x04000001 AND 0x04 to true to enable or false to disable ("tile" map2)
		0x03002871 for FE 7
		0x03003081 for FE 8
}
- How to tell if the animation will hit or miss
{
	(FE 7 only?)
	r0 + 0x29 = true for miss, false for hit or critical hit when at beginning of processor scope
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
